/**
 *    Copyright (C) 2008, 2009  Victor Smirnov <aist11@gmail.com>
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License along
 *    with this program; if not, write to the Free Software Foundation, Inc.,
 *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *    See LICENSE.exceptions in the root folder of this project for possible
 *    exceptions
 *
 */

#ifndef _CUBEFS_CORE_TOOLS_PACKED_MAP_INTRNL_H
#define _CUBEFS_CORE_TOOLS_PACKED_MAP_INTRNL_H

#include <cubefs/api/metadata.hpp>
#include <cubefs/core/tools/types/traits.hpp>

#include <iostream>
#include <typeinfo>

namespace cubefs        {
namespace tools         {

using cubefs::tools::ValueTraits;

template <typename Key>
class Accumulator {
    Key key_;
public:

    typedef Key key_t;

    Accumulator(): key_(0) {}
    Accumulator(Key key): key_(key) {}

    void operator()(Key k) {
        key_ += k;
    };

    Key get() const {
        return key_;
    }

    void Reset() {
        key_ = 0;
    }

    void Reset(Key k) {
        key_ = k;
    }

    void Sub(Key k) {
        key_ -= k;
    }
};

template <typename Key>
class Tracker {
    Key key_;
public:
    Tracker(): key_(0) {}
    Tracker(Key key): key_(key) {}

    void operator()(Key k) {
        key_ = k;
    }

    Key get() {
        return key_;
    }

    void Reset() {
        key_ = 0;
    }
};

template <typename Key>
class CompareLT {
public:
    bool operator()(Key k0, Key k1) const {
        return k0 < k1;
    }

    void Reset() {}
    void Sub(Key k) {}
    void Reset(Key k) {}
    Key get() {
        return 0;
    }

    bool TestMax(Key k, Key max) {
        return k >= max;
    }
};

template <typename Key>
class CompareLTAcc: public Accumulator<Key> {
public:
    CompareLTAcc(): Accumulator<Key>() {}

    bool operator()(Key k0, Key k1) {
        Accumulator<Key>::operator()(k1);
        return k0 < Accumulator<Key>::get();
    }

    bool TestMax(Key k, Key max) {
        return k >= max;
    }
};

template <typename Key>
class CompareLE {
public:
    bool operator()(Key k0, Key k1) const {
        return k0 <= k1;
    }
    void Reset() {}
    void Sub(Key k) {}
    void Reset(Key k) {}
    Key get() {
        return 0;
    }

    bool TestMax(Key k, Key max) {
        return k > max;
    }
};

template <typename Key>
class CompareLEAcc: public Accumulator<Key> {
public:
    CompareLEAcc(): Accumulator<Key>() {}
    bool operator()(Key k0, Key k1) {
        Accumulator<Key>::operator()(k1);
        return k0 <= Accumulator<Key>::get();
    }

    bool TestMax(Key k, Key max) {
        return k > max;
    }
};

template <typename Key>
class CompareEQ {
public:
    bool operator()(Key k0, Key k1) const {
        return k0 == k1;
    }
    void Reset() {}
    void Sub(Key k) {}
    void Reset(Key k) {}
    Key get() {
        return 0;
    }

    bool TestMax(Key k, Key max) {
        return k > max;
    }
};

template <typename Key>
class CompareEQAcc: public Accumulator<Key> {
public:
    CompareEQAcc(): Accumulator<Key>() {}
    bool operator()(Key k0, Key k1) {
        Accumulator<Key>::operator()(k1);
        return k0 == Accumulator<Key>::get();
    }

    bool TestMax(Key k, Key max) {
        return k > max;
    }
};

struct VoidValue {
    static const int SIZE = 0;
    static const Int kHashCode = 123151;
    VoidValue() {}
};

} //tools
} //cubefs

#endif //_CUBEFS_CORE_TOOLS_PACKED_MAP_INTRNL_H
